package com.cqrt.util;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

public class ExcelDateConverterUtil {
    // 支持的字符串日期格式
    private static final List<DateTimeFormatter> DATE_FORMATTERS = Arrays.asList(
        DateTimeFormatter.ofPattern("yyyy/M/d"),
        DateTimeFormatter.ofPattern("yyyy-MM-dd"),
        DateTimeFormatter.ofPattern("M/d/yyyy"),
        DateTimeFormatter.ofPattern("yyyy.M.d"),
        DateTimeFormatter.ofPattern("d-M-yyyy"),
        DateTimeFormatter.ofPattern("yyyy/MM/dd"),
        DateTimeFormatter.ofPattern("MM/dd/yyyy")
    );
    
    // 结束时间关键词
    private static final List<String> END_TIME_KEYWORDS = Arrays.asList(
        "结束", "完成", "截止", "due", "end", "finish"
    );
    
    // 数字日期匹配正则（整数或小数，如45759、45759.5）
    private static final Pattern NUMBER_PATTERN = Pattern.compile("^\\d+(\\.\\d+)?$");
    
    // Excel基准日期（1900-01-01，包含闰年bug）
    private static final LocalDate EXCEL_EPOCH = LocalDate.of(1900, 1, 1);

    /**
     * 转换Excel日期（支持数字格式和字符串格式）
     */
    public static LocalDateTime convertToLocalDateTime(String dateStr, String fieldName) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return null;
        }
        String trimmed = dateStr.trim();

        // 1. 处理数字格式的Excel日期（如45759）
        if (NUMBER_PATTERN.matcher(trimmed).matches()) {
            return parseNumberDate(trimmed, fieldName);
        }

        // 2. 处理字符串格式日期（如2025/4/12）
        return parseStringDate(trimmed, fieldName);
    }

    /**
     * 处理数字格式的Excel日期（核心修正逻辑）
     */
    private static LocalDateTime parseNumberDate(String numberStr, String fieldName) {
        try {
            double excelDate = Double.parseDouble(numberStr);
            long excelDays = (long) excelDate; // 提取整数部分（天数）

            // 步骤1：将Excel序列号转换为实际天数（关键修正！）
            // Excel序列号1对应1900-01-01，因此实际天数 = 序列号 - 1
            long days = excelDays - 1;

            // 步骤2：修正1900年闰年bug（Excel错误包含不存在的1900-02-29）
            // 对于Excel序列号>=60（即1900-03-01及之后），需再减1天
            if (excelDays >= 60) {
                days -= 1;
            }

            // 计算最终日期
            LocalDate localDate = EXCEL_EPOCH.plusDays(days);

            // 处理时间部分
            double timeFraction = excelDate - excelDays; // 小数部分（0~1）
            LocalTime localTime;

            if (isEndTimeField(fieldName)) {
                localTime = LocalTime.of(23, 59, 59); // 结束时间
            } else {
                // 转换小数部分为时间（如0.5=12:00:00）
                localTime = timeFraction > 0
                        ? LocalTime.ofSecondOfDay((long) (timeFraction * 86400))
                        : LocalTime.of(0, 0, 0);
            }

            return LocalDateTime.of(localDate, localTime);
        } catch (Exception e) {
            System.err.println("解析数字日期失败: " + numberStr + ", 错误: " + e.getMessage());
            return null;
        }
    }

    /**
     * 处理字符串格式的日期
     */
    private static LocalDateTime parseStringDate(String dateStr, String fieldName) {
        for (DateTimeFormatter formatter : DATE_FORMATTERS) {
            try {
                LocalDate localDate = LocalDate.parse(dateStr, formatter);
                LocalTime localTime = isEndTimeField(fieldName)
                        ? LocalTime.of(23, 59, 59)
                        : LocalTime.of(0, 0, 0);
                return LocalDateTime.of(localDate, localTime);
            } catch (Exception e) {
                // 忽略错误，尝试下一个格式
            }
        }
        System.err.println("解析字符串日期失败: " + dateStr);
        return null;
    }

    /**
     * 判断是否为结束时间字段
     */
    private static boolean isEndTimeField(String fieldName) {
        if (fieldName == null) {
            return false;
        }
        String lower = fieldName.toLowerCase();
        return END_TIME_KEYWORDS.stream().anyMatch(lower::contains);
    }
}